home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / newsgrp / group93b.txt / 000087_icon-group-sender _Fri May 14 12:10:26 1993.msg < prev    next >
Internet Message Format  |  1993-06-16  |  4KB

  1. Received: by cheltenham.cs.arizona.edu; Fri, 14 May 1993 10:39:05 MST
  2. Date: Fri, 14 May 93 12:10:26 CDT
  3. From: "Richard L. Goerwitz" <goer@midway.uchicago.edu>
  4. Message-Id: <9305141710.AA04578@midway.uchicago.edu>
  5. To: icon-group@cs.arizona.edu
  6. Subject: string stripping
  7. Status: R
  8. Errors-To: icon-group-errors@cs.arizona.edu
  9.  
  10. This is a long posting, but I hope it will be helpful.  We have a lot
  11. of quite newbies online here, and they should be let in on the fun.  For
  12. Sean it might be a bit simplistic, seeing as he's been using Icon for a
  13. while.  Bear with me Sean, and I'll offer you several distinct answers
  14. to your question!
  15.  
  16. Sean states:
  17.  
  18.     If i have a string and i want to strip out certain characters
  19.     (internal ones, so trim won't do it), ...
  20.  
  21. This is a good problem, and I'll bet that everyone who programs with
  22. strings a lot has had to perform this chore.  It's a perfect set-up for
  23. a discussion of string scanning.
  24.  
  25. Here's your code:
  26.  
  27.     # assume you want to remove hyphens and periods
  28.     full := "abc-def.ghi"
  29.     bare := ""
  30.     badchars := '-.'
  31.  
  32.     every c := !full do
  33.        # test whether the intersection of c and badchars is empty
  34.        if *(c ** badchars) = 0 then bare ||:= c
  35.  
  36. This is perfectly good code, and nicely formatted.  The only problem
  37. with it I can see is that it doesn't take advantage of string scanning,
  38. and its elegance/optimizations.  Let's use our full, bare, and badchars
  39. variables above, and try again using scanning:
  40.  
  41.     full ? {
  42.         while bare ||:= tab(upto(badchars)) do
  43.         tab(many(badchars))
  44.         bare ||:= tab(0)
  45.     }
  46.  
  47. This actually subsumes a lot of stuff.  Assume that our current position
  48. is initially 1, and that position 0 means the end of the string (note the
  49. distinct use of the zero offset in Icon, allowing us not to worry about
  50. string lengths):
  51.  
  52.     1) append everything in full, from our current position up to the
  53.        next occurrence of a badchar, to bare; if there are no badchars
  54.        left in full, do step 4
  55.     2) go past however many badchars we have found, and reset our cur-
  56.        rent position to just before the next "good" char
  57.     3) then do 1 again
  58.     4) append everything from the current position to the end of the
  59.        string to bare
  60.  
  61. Scanning, once you get the feel for it, is pretty clear, and usually very
  62. elegant.  And although people don't use Icon, Prolog, LISP, etc. for their
  63. blinding speed, the scanning process is optimized, so you get relatively
  64. good performance.  Note that if you prefer a less thoroughly Iconish solu-
  65. tion to your problem, you could write the following as a kind of compro-
  66. mise:
  67.  
  68.     every c := !full do
  69.        # test whether the intersection of c and badchars is empty
  70.        if any(badchars, c) then bare ||:= c
  71.  
  72. But here again, the temptation to use Icon's backtracking features for more
  73. general expression of the problem is almost irresistable:
  74.  
  75.     every bare ||:= !full -- badchars
  76.  
  77. I don't find this as clear as the scanning method, so I'd probably want to
  78. prepend a comment:
  79.  
  80.     # bare defined as full stripped of badchars
  81.     every bare ||:= !full -- badchars
  82.  
  83. If you want, you can use encapsulation via recursive function calls to get
  84. rid of the assignment altogether:
  85.  
  86.     procedure stripbads(full, badchars)
  87.         if *full = 0 then return ""
  88.         return (full[1] -- badchars) || strip(full[2:0], badchars)
  89.     end
  90.  
  91. This is starting to look LISPish, though, and I personally find it verbose
  92. and somewhat opaque.
  93.  
  94. Note that I haven't tested any of this code, so if you find any bugs, please
  95. don't be too shocked.  My internal Icon interpreter still isn't fully iso-
  96. morphic with the real one.
  97.  
  98. I'd love to teach an Icon course some day, but that's not the typical way in
  99. which philologists normally find employment :-).
  100.  
  101.  
  102. -Richard Goerwitz
  103.  goer@midway.uchicago.edu
  104.